﻿
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
namespace XamlDom.Parser
{
    public sealed class XamlParser
    {
        private string _xaml;

        public XamlParser(string xaml)
        {
            _xaml = xaml;
        }

        /// <summary>
        /// 这个地方分层次进行解析
        /// 有以下几个概念：
        /// 解析对象，解析属性，解析属性值
        /// 其中属性分为普通属性，依赖属性和附加属性
        /// 找到相应的属性值
        /// </summary>
        /// <returns></returns>
        public XamlNode Parse()
        {
            XamlNode rootNode = null;

            Stack<XamlNode> nodeStack = new Stack<XamlNode>();

            XmlReader xmlReader = XmlReader.Create(new StringReader(_xaml));

            while (xmlReader.Read())
            {
                XmlNodeType nodeType = xmlReader.NodeType;

                Debug.WriteLine(xmlReader.LocalName + "-" + nodeType.ToString());

                switch (nodeType)
                {
                    case XmlNodeType.Element:
                        XamlNode elementNode = new XamlNode(xmlReader.LocalName,xmlReader.NamespaceURI);
                        nodeStack.Push(elementNode);

                        if (xmlReader.HasAttributes)
                        {
                            while (xmlReader.MoveToNextAttribute())
                            {
                                string attributeName = xmlReader.Name;
                                string attributeValue = xmlReader.Value;

                                XamlAttribute attributeNode = new XamlAttribute(attributeName, attributeValue);
                                elementNode.Attributes.Add(attributeNode);
                            }
                            xmlReader.MoveToElement();
                        }
                        break;
                    case XmlNodeType.Whitespace:
                        nodeStack.Push(new XamlNode("-----", ""));
                        break;
                    case XmlNodeType.EndElement:
                        XamlNode currentNode = nodeStack.Pop();
                        if (rootNode != null)
                        {
                            if (currentNode.NodeName.Equals("-----"))
                            {
                                currentNode = nodeStack.Pop();
                                rootNode.ParentNode = currentNode;
                                currentNode.LastChildNode = rootNode;
                                rootNode = currentNode;
                            }
                            else
                            {
                                rootNode.NextNode = currentNode;
                                currentNode.PreNode = rootNode;
                                rootNode = currentNode;
                            }
                        }
                        else
                        {
                            rootNode = currentNode;
                        }
                        if (nodeStack.Count > 0)
                        {
                            nodeStack.Pop();
                        }
                        break;
                }
            }
            return rootNode;
        }
    }
}
